package com.example.myapplication10.Activities;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import com.alibaba.fastjson2.JSONObject;
import com.example.myapplication10.DTO.WeatherDTO;
import com.example.myapplication10.MsgEvents.MsgEventAddCity;
import com.example.myapplication10.MsgEvents.MsgEventAddIntent;
import com.example.myapplication10.MsgEvents.MsgEventException;
import com.example.myapplication10.MsgEvents.MsgEventInit;
import com.example.myapplication10.MsgEvents.MsgEventOver;
import com.example.myapplication10.MsgEvents.MsgEventRemoveCity;
import com.example.myapplication10.MsgEvents.MsgEventRemoveIntent;
import com.example.myapplication10.MsgEvents.MsgEventTitle;
import com.example.myapplication10.MsgEvents.MsgEventUpdateTime;
import com.example.myapplication10.MsgEvents.MsgEventWeather;
import com.example.myapplication10.MsgEvents.MsgEventWeatherUpdate;
import com.example.myapplication10.R;
import com.example.myapplication10.Utils.ISubject;
import com.google.android.material.tabs.TabLayout;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MyAdapter extends FragmentStateAdapter implements ISubject {
    private WeatherDTO weather = new WeatherDTO();
    public boolean isFragVisibility = false;
    public int maxPages = 2;
//    private final List<WeatherFrag1> fragmentList = new ArrayList<>();
    public int initPosition = 0;
    public int position = 0;
    public int tabPosition = 0;
    public String titleName = "请添加城市";
    boolean updateFlag = false;boolean updateExecute = false;
    boolean initFlag;boolean initExecute = false;
    boolean addFlag = false;boolean addExecute = false;
    boolean failFlag = false;
    public ArrayList<Map<String, String>> cityList = new ArrayList<>();
    public ArrayList<Map<String, String>> addCityList = new ArrayList<>();
    public ArrayList<WeatherDTO> cityWeatherList = new ArrayList<>();
    public List<Fragment> fragmentList = new ArrayList<>();
    public TabLayout tabLayout;
    public final Thread updateThread;public final Thread initThread;public final Thread addThread;

    //    public void setItemCount(int itemCount) {
//        this.itemCount = itemCount;
//    }
    public static String getWeatherJson(String url) throws IOException {
        OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5000, TimeUnit.MILLISECONDS).build();
        Request request = new Request.Builder().url(url).build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            return response.body().string();
        } else {
//            Thread.sleep(2000);
            throw new IOException("Unexpected code " + response);
        }
    }

    public void setCityListFromHistory(ArrayList<Map<String, String>> cityListFromHistory) {
        this.cityList = cityListFromHistory;
        addFlag = false;
        updateFlag = false;
    }
    public MyAdapter(Context ctx,TabLayout tabLayout, ArrayList<TabLayout.Tab> tabs,
                     ArrayList<Map<String, String>> cityList, List<Fragment> fragments,
                     @NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle)  {
        super(fragmentManager, lifecycle);
        EventBus.getDefault().register(this);
        this.cityWeatherList = new ArrayList<WeatherDTO>();
//        tv=findViewById(R.id.tv1);
        this.tabLayout = tabLayout;
        initFlag = true;
        isFragVisibility = true;

//        ArrayList<Map<String,String>> cityList = new ArrayList<>();
//        Map<String,String> map = new HashMap<>();
//        Set<String> setCityName = new HashSet<>();
//        Set<String> setCityCode = new HashSet<>();

//        cityList.add(map);

//        setCityName.add(map.get("城市名称"));
//        setCityCode.add(map.get("城市代码"));
//        map = new HashMap<>();
//        map.put("城市名称","金华");
//        map.put("城市代码","101210901");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","杭州");
//        map.put("城市代码","101210101");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","舟山");
//        map.put("城市代码","101211101");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","北京");
//        map.put("城市代码","101010100");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","上海");
//        map.put("城市代码","101020100");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","广州");
//        map.put("城市代码","101280101");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","深圳");
//        map.put("城市代码","101280601");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","南京");
//        map.put("城市代码","101190101");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
//        map = new HashMap<>();
//        map.put("城市名称","成都");
//        map.put("城市代码","101270101");
////        setCityName.add(map.get("城市名称"));
////        setCityCode.add(map.get("城市代码"));
//        cityList.add(map);
        this.cityList = cityList;
        this.addCityList = new ArrayList<>();
        initThread = new Thread(new InitThread());
        updateThread = new Thread(new UpdateThread());
        addThread = new Thread(new AddThread());
        initThread.start();
        updateThread.start();
        addThread.start();


    }
//        this.weather = weather0;
//        ArrayList<Map<String,String>> cityList = new ArrayList<>();
//        Set<String> setCityName = new HashSet<>();
//        Set<String> setCityCode = new HashSet<>();
//        SharedPreferences sharedPreferences =
//                ctx.getSharedPreferences("weather",Activity.MODE_PRIVATE);
//        setCityName = sharedPreferences.getStringSet("城市名称",null);
//        setCityCode = sharedPreferences.getStringSet("城市代码",null);
//        Iterator<String> iterator1 = setCityName.iterator();
//        Iterator<String> iterator2 = setCityCode.iterator();
//        while (iterator1.hasNext()){
//            Map<String,String> map = new HashMap<>();
//            map.put("城市名称",iterator1.next());
//            map.put("城市代码",iterator2.next());
//            cityList.add(map);
//        }
//        this.itemCount = itemCount;

    public String getCityString(){
        StringBuilder stringBuilder = new StringBuilder();
        for (Map<String, String> map : this.cityList){
            String string = map.get("城市名称");
            stringBuilder.append(string);
            stringBuilder.append("\":\"");
            string = map.get("城市代码");
            stringBuilder.append(string);
            stringBuilder.append("\",\n");
        }
        return stringBuilder.toString();
    }

    public void setTabLayout(ArrayList<TabLayout.Tab> tabs){
        TabLayout tabLayout = this.tabLayout;
        TabLayout.OnTabSelectedListener onTabSelectedListener =
                new TabLayout.OnTabSelectedListener(){

                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                        tab.setCustomView(R.layout.selected);
                        tabPosition = tabs.indexOf(tab);
                        WeatherDTO weather1 = cityWeatherList.get(tabs.indexOf(tab));
                        EventBus.getDefault().post(new MsgEventUpdateTime(weather1.getCityInfo().getUpdateTime()));
                        titleName = cityList == null || cityList.size() == 0 ?
                                "请添加城市":cityList.get(tabs.indexOf(tab)).get("城市名称");
                        EventBus.getDefault().post(new MsgEventTitle(titleName));
//                        EventBus.getDefault().post(new MsgEventUpdate(updateTime));
                    }

                    @Override
                    public void onTabUnselected(TabLayout.Tab tab) {
                        tab.setCustomView(R.layout.unselected);
                    }

                    @Override
                    public void onTabReselected(TabLayout.Tab tab) {
                        tab.setCustomView(R.layout.selected);
                    }
                };
        tabLayout.addOnTabSelectedListener(onTabSelectedListener);
        tabLayout.setSelectedTabIndicator(null);
    }

    @Override
    public void addObserver(Fragment obj) {

    }

    @Override
    public void deleteObserver(Fragment obj) {

    }


    //    public void initCityView() {
//        tabLayout = findViewById(R.id.tab_layout);
//        tabs = new ArrayList<>();
//        tabs = new ArrayList<>();
//        adapter = new MyAdapter(this.getBaseContext(), viewList, getSupportFragmentManager(), getLifecycle());
//        viewPager2 = findViewById(R.id.weather_view0);
//        viewPager2.setAdapter(adapter);
//        TabLayout.OnTabSelectedListener onTabSelectedListener =
//                new TabLayout.OnTabSelectedListener(){
//
//                    @Override
//                    public void onTabSelected(TabLayout.Tab tab) {
//                        tab.setCustomView(R.layout.selected);
//                        setTitle(cityList.get(tabs.indexOf(tab)).get("城市名称"));
//                    }
//
//                    @Override
//                    public void onTabUnselected(TabLayout.Tab tab) {
//                        tab.setCustomView(R.layout.unselected);
//                    }
//
//                    @Override
//                    public void onTabReselected(TabLayout.Tab tab) {
//                        tab.setCustomView(R.layout.selected);
//                    }
//                };
//        tabLayout.addOnTabSelectedListener(onTabSelectedListener);
//        tabLayout.setSelectedTabIndicator(null);
//        new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
//            @Override
//            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
//                tab.setCustomView(R.layout.unselected);
//                tabs.add(position,tab);
//            }
//        }).attach();
//    }
    private void first() {

        String msg = "";
        weather = new WeatherDTO();
//                int itemCount0 = cityList.size();
        Map<String, String> map = cityList.get(initPosition);
        String cityCode = map.get("城市代码");
        try {
//                                Thread.sleep(500);
            msg = getWeatherJson("http://t.weather.sojson.com/api/weather/city/" + cityCode);
        } catch (IOException e) {
            failFlag = true;
            initFlag = false;
            try {
                Thread.sleep(100);
                EventBus.getDefault().post(new MsgEventOver(e.getLocalizedMessage()));
                Thread.sleep(20000);
            } catch (InterruptedException ex) {

            }
        }
        JSONObject object = JSONObject.parseObject(msg);
        weather = object.toJavaObject(WeatherDTO.class);
        isFragVisibility = true;
        if (cityList.size() == 1) {
            EventBus.getDefault().post(new MsgEventInit(weather));
            EventBus.getDefault().post(new MsgEventOver(cityList.get(0).get("城市名称")));
//                        itemCount = itemCount0;
        } else {
            EventBus.getDefault().post(new MsgEventWeather(weather));
//                        if (cityList.indexOf(map) == 0) {
//                            EventBus.getDefault().post(new MsgEventInit(weather));
//                        } else {
//                            EventBus.getDefault().post(new MsgEventWeather(weather));
//                        }

        }
    }

    class InitThread implements Runnable {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    if(initFlag && cityList != null && isFragVisibility){
                        first();
                        initPosition+=1;
                        initFlag = cityList.size() != initPosition;
                    }
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }
//                int size = cityList.size();
//                int tabPos = tabPosition;
//                int fragPos = position;
//                if (fragPos == -1) {
//                    for(int i = 0 ;i < maxPages;i++){
//                        first();
//                    }
//                } else if (fragPos + 1 == size) {
//                    EventBus.getDefault().post(new MsgEventOver(cityList.get(tabPosition).get("城市名称")));
//                } else {
//                    if ((fragPos + 1) % maxPages == 0) {
//                        try {
//
//                            EventBus.getDefault().post(new MsgEventOverBackGround(cityList.get(tabPosition).get("城市名称")));
//                            Thread.sleep(500);
//                            if(tabPos < osition){
//                                first();
//
//                            }
//                        } catch (InterruptedException e) {
//                            throw new RuntimeException(e);
//                        }
//                    }
//                    else {
//
//                    }
//                }
//
//            }
//        }
//
//    }
    class AddThread implements Runnable {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    addWeather();
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }

    private void addWeather() {
        position =cityWeatherList.size()-1;
        if (addExecute && addCityList != null && addCityList.size() != 0) {
            String msg;
            weather = new WeatherDTO();
            //                int itemCount0 = cityList.size();
            for (Map<String, String> map : addCityList) {
                String cityCode = map.get("城市代码");
                try {
//                                Thread.sleep(500);
                    msg = getWeatherJson("http://t.weather.sojson.com/api/weather/city/" + cityCode);
                } catch (IOException e) {
                    failFlag = true;
                    try {
                        Thread.sleep(100);
                        EventBus.getDefault().post(new MsgEventOver(e.getLocalizedMessage()));
                        Thread.sleep(20000);
                    } catch (InterruptedException ex) {
                        throw new RuntimeException(ex);
                    }
                    throw new RuntimeException(e);
                }
                JSONObject object = JSONObject.parseObject(msg);
                weather = object.toJavaObject(WeatherDTO.class);
                EventBus.getDefault().post(new MsgEventWeather(weather));

            }
            cityList.addAll(addCityList);
            addCityList.clear();
            addExecute = false;

        }
    }

    class UpdateThread implements Runnable {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    updateWeather();
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }

    private void updateWeather() {
        if(updateFlag && cityList != null) {
            String msg;
            weather = new WeatherDTO();
            String cityCode = cityList.get(position).get("城市代码");
            try {
                msg = getWeatherJson("http://t.weather.sojson.com/api/weather/city/" + cityCode);
            } catch (IOException e) {
                failFlag = true;
                try {
                    Thread.sleep(100);
                    EventBus.getDefault().post(new MsgEventOver(e.getLocalizedMessage()));
                    Thread.sleep(20000);
                } catch (InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
                throw new RuntimeException(e);
            }
            JSONObject object = JSONObject.parseObject(msg);
            weather = object.toJavaObject(WeatherDTO.class);
            cityWeatherList.set(position, weather);
            notifyObserver(position);
            updateFlag = false;
        }
    }


//            for (Map<String,String> map:cityList){
//                String cityCode = map.get("城市代码");
//                try {
//                    msg = getWeatherJson("http://t.weather.sojson.com/api/weather/city/" + cityCode);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//                JSONObject object = JSONObject.parseObject(msg);
//                weather = object.toJavaObject(Weather.class);
//                if(cityList.indexOf(map) == 0) {
//                    EventBus.getDefault().post(new MsgEventInit(weather));
//                    itemCount = itemCount0;
//                }
//                else{EventBus.getDefault().post(new MsgEventWeather(weather));}
//            }


    public void notifyObserver(int position) {
        WeatherDTO weather1 = this.cityWeatherList.get(position);
//        WeatherFrag1 weatherFrag1 = fragmentList.get(position);
        EventBus.getDefault().post(new MsgEventWeatherUpdate(weather1));
    }

//        weatherFrag1.updateDataSet(weather1);
//        return this.fragments.get(position);
//        this.position = position;
//        if (fragments.get(position) == null){
//            this.fragments.set(position, new weatherFrag1());
//        }
//        return this.fragments.get(position);
//    public String getTitle() {
//        return this.titleName;
//    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {

//        if (isFragVisibility){
//            isFragVisibility = false;
////            this.initPosition = position;
//        }
//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }

        WeatherFrag1 weatherFrag1 = new WeatherFrag1(cityWeatherList.get(position));

        this.position = position;
        fragmentList.add(weatherFrag1);
        return weatherFrag1;
    }

//    @Subscribe(threadMode = ThreadMode.MAIN)
//    public void messageEventBusEndThread(MsgEventEndThread event) {
//
//    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageEventBusWeather(MsgEventWeather event) throws InterruptedException {
        WeatherDTO weather = event.getMsg();
        cityWeatherList.add(weather);
        this.position += 1;
        if (addFlag) {
            EventBus.getDefault().post(new MsgEventAddIntent(cityList.get(tabPosition).get("城市名称")));
            addFlag = false;
        }
        else{
            if (cityWeatherList.get(cityWeatherList.size()-1)
                    .getCityInfo().getCity().contains
                            (Objects.requireNonNull(
                                    cityList.get(cityList.size() - 1)
                                            .get("城市名称")))){
                EventBus.getDefault().post(new MsgEventOver(cityList.get(cityWeatherList.size()-1).get("城市名称")));
            }

        }
    }
//        if (weather.getCityInfo().getCity().contains
//                (Objects.requireNonNull(cityList.get(cityList.size() - 1).get("城市名称")))){
//            EventBus.getDefault().post(new MsgEventOver(cityList.get(tabPosition).get("城市名称")));
//
//        }
//        EventBus.getDefault().post(new MsgEventTitle(isOver));

//    @Subscribe(threadMode = ThreadMode.POSTING)
//    public void messageEventBusWeatherUpdate(MsgEventWeatherUpdate event) throws InterruptedException {
//        Weather weather = event.getMsg();
//        cityWeather.set(weather);
//        Thread.sleep(100);
//        if (weather.getCityInfo().getCity().contains
//                (Objects.requireNonNull(cityList.get(cityList.size() - 1).get("城市名称")))){
//            EventBus.getDefault().post(new MsgEventOver(cityList.get(tabPosition).get("城市名称")));
//        }
//
////        EventBus.getDefault().post(new MsgEventTitle(isOver));
//    }
//    public TabLayout getTabLayout() {
//        return tabLayout;
//    }

//    public void setTabLayout(TabLayout tabLayout) {
//        this.tabLayout = tabLayout;
//    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageEventAddCity(MsgEventAddCity event) {
        Map<String,String> map = event.getMsg();
//        this.addFlag = true;
//        this.addExecute = true;
//        EventBus.getDefault().post(new MsgEventAddIntent("success"));

            if (!addCityList.contains(map) && !cityList.contains(map)){
                this.addCityList.add(map);
                addExecute = true;
                addFlag = true;
            }
            else {
                EventBus.getDefault().post(new MsgEventException("此城市已添加，不能重复添加！\n点击确定返回上一页"));
            }

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageEventRemoveCity(MsgEventRemoveCity event) {
        Map<String,String> map = event.getMsg();
        EventBus.getDefault().post(new MsgEventRemoveIntent(map));

            if (cityList.contains(map)){
                this.cityWeatherList.remove(cityList.indexOf(map));
                this.cityList.remove(map);
        }

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageEventBusInit(MsgEventInit event) throws InterruptedException {
        WeatherDTO weather = event.getMsg();
        cityWeatherList.add(weather);


        //        this.setWeather(weather);
//        this.createFragment(this.position);
//        this.tabLayout = tabLayout;
//        this.tabs = tabs;
    }

    public WeatherDTO getWeather() {
        return weather;
    }

    public void setWeather(WeatherDTO weather) {
        this.weather = weather;
    }

//    public int getPosition() {
//        return position;
//    }

    public void setUpdatePosition(int updatePosition) {
        this.position = updatePosition;
        this.updateFlag = true;
    }

//    public int getPositionNow() {
//        return this.position;
//    }


//    @Subscribe(threadMode = ThreadMode.MAIN)
//    public void messageEventBus(MsgEvent event) {
//        String str = event.getMsg();
////        Weather weather = new Weather();
////        CityInfoDTO cityInfo = new CityInfoDTO();
////        DataDTO data = new DataDTO();
////        YesterdayDTO yesterday = new YesterdayDTO();
////        List<ForecastDTO> forecastArrayList = new ArrayList<>();
//        JSONObject obj = JSONObject.parseObject(str);
////        setTitle(cityName);
//        if (obj.getInteger("status") == 200) {
////            initViews();
////            notifyObserver();
//            EventBus.getDefault().post(new MsgEventData(str));
//            MsgEventData msgEventData = new MsgEventData(str);
//            weatherFrag1 weatherFrag01 = new weatherFrag1();
//            weatherFrag01.messageEventBus(msgEventData);
//        }
//    }


    @Override
    public int getItemCount() {

        return cityWeatherList == null?0:
                cityWeatherList.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public boolean containsItem(long itemId) {
        return itemId >= 0 && itemId < getItemCount();
    }
}
